package com.example.medispider.service.master;

import com.example.medispider.pojo.master.SettlementMaster;
import com.example.medispider.service.listener.MediSpiderListener;
import com.example.medispider.service.pipeline.ExcelPipeline;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.SpiderListener;
import us.codecraft.webmagic.model.HttpRequestBody;
import us.codecraft.webmagic.utils.HttpConstant;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class MasterDataExecutor {
    private static final String REQUEST_URL = "https://portal.hub.hsip.gov.cn/mbs-dy-420500/web/tbkSetlQuery/querySetlInfoForExport";
    private static final String FRONT_URL = "https://portal.hub.hsip.gov.cn/mbs/mbs-dy-420500-ui/N1407.html#/N140702";
    private final MasterPageProcessor masterPageProcessor;
    private final List<SpiderListener> mediSpiderListeners = new ArrayList<>();
    private int threadNum = 10; // 默认值10
    /**
     * 分页大小
     */
    private int pageSize = 100; // 默认值100
    /**
     * 开始日期
     */
    private String qbegndate;
    /**
     * 截至日期
     */
    private String qenddate;
    /**
     * 参保区域编码
     */
    private String insuAdmdvs = "";
    /**
     * 医疗机构编码
     */
    private List<String> fixmedinsCodeList = new ArrayList<>();
    /**
     * 输出文件路径
     */
    private String outputFilePath;

    /**
     * 构造函数
     *
     * @param masterPageProcessor 爬虫执行器
     * @param mediSpiderListener  爬虫监听器
     */
    @Autowired
    public MasterDataExecutor(MasterPageProcessor masterPageProcessor, MediSpiderListener mediSpiderListener) {
        this.masterPageProcessor = masterPageProcessor;
        this.mediSpiderListeners.add(mediSpiderListener);
    }

    /**
     * 执行方法
     */
    public void run() {
        // 新建 Pipeline
        ExcelPipeline<SettlementMaster> masterPipeline = new ExcelPipeline<>(outputFilePath, SettlementMaster.class);
        // 创建 Spider 并添加请求
        Spider spider = Spider.create(masterPageProcessor)
                .addPipeline(masterPipeline)
                .setSpiderListeners(mediSpiderListeners)
                .thread(threadNum);
        for (String fixmedinsCode : fixmedinsCodeList) {
            Request request = createRequest(fixmedinsCode);
            spider.addRequest(request);
        }
        try {
            // 执行 Spider
            spider.run();
        } catch (Exception e) {
            System.err.println("爬取结算主单时出错：" + e.getMessage());
        } finally {
            // 关闭Pipeline
            masterPipeline.close();
        }
    }

    /**
     * 创建 Request
     *
     * @param fixmedinsCode 医疗机构代码
     * @return Request
     */
    private Request createRequest(String fixmedinsCode) {
        // 创建 Request 对象
        Request request = new Request(REQUEST_URL);
        request.setMethod(HttpConstant.Method.POST); // 设置请求方法为 POST
        // 准备 POST 请求体参数
        HttpRequestBody httpRequestBody = createHttpRequestBody(fixmedinsCode);
        request.setRequestBody(httpRequestBody);
        return request;
    }

    /**
     * 创建 POST 请求体
     *
     * @param fixmedinsCode 医疗机构代码
     * @return HttpRequestBody
     */
    private HttpRequestBody createHttpRequestBody(String fixmedinsCode) {
        Map<String, Object> params = new HashMap<>();
        params.put("pageNum", 1);
        params.put("pageSize", pageSize);
        params.put("qbegndate", qbegndate);
        params.put("qenddate", qenddate);
        params.put("medType", "");
        params.put("spPsnType", "");
        params.put("psnType", "");
        params.put("insuAdmdvs", insuAdmdvs);
        params.put("doPage", 1);
        params.put("fixmedinsCode", fixmedinsCode);
        params.put("_modulePartId_", "");
        params.put("frontUrl", FRONT_URL);
        // 将参数设置为表单格式的请求体，并指定编码
        HttpRequestBody httpRequestBody = HttpRequestBody.form(params, StandardCharsets.UTF_8.name());
        return httpRequestBody;
    }


    public MasterDataExecutor setPageSize(int pageSize) {
        if (pageSize <= 0) {
            throw new IllegalArgumentException("pageSize must be positive");
        }
        this.pageSize = pageSize;
        return this;
    }

    public MasterDataExecutor setQbegndate(String qbegndate) {
        this.qbegndate = qbegndate;
        return this;
    }

    public MasterDataExecutor setQenddate(String qenddate) {
        this.qenddate = qenddate;
        return this;
    }

    public MasterDataExecutor setInsuAdmdvs(String insuAdmdvs) {
        this.insuAdmdvs = insuAdmdvs;
        return this;
    }

    public MasterDataExecutor setFixmedinsCode(ArrayList<String> fixmedinsCodeList) {
        this.fixmedinsCodeList = fixmedinsCodeList;
        return this;
    }

    public MasterDataExecutor setThreadNum(int threadNum) {
        this.threadNum = threadNum;
        return this;
    }

    public MasterDataExecutor setOutputFilePath(String outputFilePath) {
        this.outputFilePath = outputFilePath;
        return this;
    }
}
